#include "renderwidget.h"


RenderWidget::RenderWidget(QWidget *parent) : QWidget(parent)
{
    resize(parent->width(), parent->height());
    nx=parent->width();
    ny=parent->height();
    int cx, cy;
    if( NULL == parent )
    {

       cx = (screen()->availableSize().width() - width()) / 2;
       cy = (screen()->availableSize().height() - height()) / 2;
    }
    //否则，控件就显示在父部件中央
    else
    {
       cx = ( parent->width() - width() ) / 2;
       cy = ( parent->height() - height() ) / 2;
    }
    move(cx, cy);
    image=new QImage(nx,ny,QImage::Format_RGB32);
    image->fill(QColor(54,54,54,100));

    renderThread*rentrs[QThread::idealThreadCount()];
//     QThreadPool::globalInstance()->setMaxThreadCount(12);
    QThread*rts[QThread::idealThreadCount()];
    initScene();
    int row=3;
    int col=QThread::idealThreadCount()/row;
    int total=0;
    int dnx,dny;
    int r=16,c=9;
//    for(int u=0;u<r;u++)
//    {
//        for(int v=0;v<c;v++)
//        {
////            dnx=nx*u/r;
////            dny=ny*v/c;
//          dnx=nx/r;
//          dny=ny/c;
            for(int i=0;i<row;i++)
            {

                for(int j=0;j<col;j++)
                {

        //            qDebug()<<i*col+j<<":"<<(nx/col)*j<<","<<(nx/col)*(j+1)<<"\n";

                    rentrs[i*col+j]=new renderThread;
                    renderThread*rentr=rentrs[i*col+j];

                    rts[i*col+j]=new QThread(this);
                    QThread*rt=rts[i*col+j];

                    rentr->moveToThread(rt);

                    connect(this,&RenderWidget::renderImage,rentr,&renderThread::render);
                    connect(rentr,&renderThread::refresh,this,[=](){update();});
                    //等工作的QObject结束，让线程停止结束
                    connect(rentr,&renderThread::renderfinished,this,[&](QThread*tr){
                        total+=1;
                        qDebug()<<tr<<"结束\n";
                        tr->quit();
                        tr->wait();

                    });
                    //线程停止发给QObject让他自己销毁。
                    connect(rt, &QThread::finished,rentr, &renderThread::deleteLater);
                    // QObject销毁之后，让线程自己销毁。
                    connect(rentr, &renderThread::destroyed, rt, &QThread::deleteLater);

                    rt->start();
                    emit renderImage(rentr,sc,image,nx,ny,(nx/col)*j,(nx/col)*(j+1),(ny/row)*i,(ny/row)*(i+1));
                }
            }
//        }
//    }


}
void RenderWidget::paintEvent(QPaintEvent*e)
{
    QPainter painter(this);
    QRect rect(0,0,width(),height());
    painter.drawImage(rect,*image);
    painter.end();
}

void RenderWidget::initScene()
{
    int count=5;
    hitable*list[count];
//    image_texture*earthtex=new image_texture(new QImage(":/test.jpeg"));
    list[0]=new sphere(QVector3D(0,0,-1),0.5,new metal(QVector3D(0.6,0.6,.6),0.1));
    list[1]=new sphere(QVector3D(0,-100.5,-1),100,new lambertian(new constant_texture(QVector3D(0.5,0.5,0.5))));//new noise_texture
//    list[2]=new moving_sphere(QVector3D(1,0,-1),QVector3D(1,0,-1),0.0,1.0,0.5,new lambertian(earthtex));
    list[2]=new sphere(QVector3D(-1,0,-1),0.5,new dielectric(1.5));
    list[3]=new moving_sphere(QVector3D(2,0,-1),QVector3D(2,0,-1),0.0,1.0,0.5,new lambertian(new constant_texture(QVector3D(0.3,0.3,0.3))));
    list[4]=new sphere(QVector3D(3,0,-1),0.5,new metal(QVector3D(0.7,0.8,.8),0.1));

    hitable*world=new bvh_node(list,count,0,1);
    QVector3D lookfrom=QVector3D(5,3,-6);
    QVector3D lootat=QVector3D(1,0,-1);
    float aperture=0.1;
    float dist_to_focus=(lookfrom-lootat).length();
    camera*cam=new camera(lookfrom,lootat,QVector3D(0,1,0),50,float(nx)/float(ny),aperture,dist_to_focus,0.0,1.0);
    sc=new scene(cam,world);
}

